~ chicken-core (master) /manual/Module (chicken process)


  1[[tags: manual]]
  2[[toc:]]
  3
  4== Module (chicken process)
  5
  6This module offers procedures for interacting with subprocesses.
  7
  8Note:
  9Errors caused by underlying C calls that
 10change errno will produce a condition object with an {{errno}}
 11property, which can be accessed with
 12{{(get-condition-property <the-condition-object> 'exn 'errno)}}.
 13
 14=== Processes
 15
 16==== process-execute
 17
 18<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-ALIST]])</procedure>
 19
 20Replaces the running process with a new process image from the program
 21stored at {{PATHNAME}}, using the C library function {{execvp(3)}}.
 22If the optional argument {{ARGUMENT-LIST}} is given, then it should
 23contain a list of strings which are passed as arguments to the subprocess.
 24If the optional argument {{ENVIRONMENT-ALIST}} is supplied, then the library
 25function {{execve(2)}} is used, and the environment passed in
 26{{ENVIRONMENT-ALIST}} (which should be of the form {{(("<NAME>" . "<VALUE>") ...)}})
 27is given to the invoked process. Note that {{execvp(3)}} respects the
 28current setting of the {{PATH}} environment variable while {{execve(3)}} does not.
 29
 30This procedure never returns; it either replaces the process with a new one
 31or it raises an exception in case something went wrong executing the program.
 32
 33On Windows, these procedures all have an additional optional parameter
 34{{EXACT-FLAG}}, which defaults to {{#f}}. When {{#f}} is passed, any
 35argument string with embedded whitespace will be wrapped in
 36quotes. When {{#t}} no such wrapping occurs.
 37
 38
 39==== process-fork
 40
 41<procedure>(process-fork [THUNK [KILLOTHERS?]])</procedure>
 42
 43Creates a new child process with the UNIX system call
 44{{fork()}}. In the parent process this procedure returns a process-object representing the child process
 45and in the child process {{process-fork}} returns {{#f}}.
 46If {{THUNK}} is given, then the child process calls it as a procedure
 47with no arguments and terminates. If {{THUNK}} is given and the
 48optional argument {{KILLOTHERS?}} is true, then kill all other
 49existing threads in the child process, leaving only the current thread
 50to run {{THUNK}} and terminate.
 51
 52'''NOTE''': On native Windows builds (all except cygwin), this
 53procedure is unimplemented and will raise an error.
 54
 55==== process-run
 56
 57<procedure>(process-run COMMANDLINE)</procedure><br>
 58<procedure>(process-run COMMAND ARGUMENT-LIST)</procedure>
 59
 60Creates a new child process. The process object representing the new process is returned.
 61
 62* The single parameter version passes the {{COMMANDLINE}} to the
 63system shell, so usual argument expansion can take place.  Be careful
 64to properly quote arguments with the {{qs}} procedure to avoid shell
 65injection vulnerabilities.
 66* The multiple parameter version directly invokes the {{COMMAND}} with
 67the {{ARGUMENT-LIST}}, and is vastly preferred over the
 68single-parameter version because of its better safety.
 69
 70==== process-signal
 71
 72<procedure>(process-signal PROCESS [SIGNAL])</procedure>
 73
 74Sends {{SIGNAL}} to the process with the integer id or prcoess
 75object {{PROCESS}} using the
 76UNIX system call {{kill()}}. {{SIGNAL}} defaults to the value
 77of the variable {{signal/term}}.
 78
 79'''NOTE''': On native Windows builds (all except cygwin), this
 80procedure is unimplemented and will raise an error.
 81
 82==== process-spawn
 83
 84<procedure>(process-spawn MODE COMMAND [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure>
 85
 86Creates and runs a new process with the given {{COMMAND}} filename and
 87the optional {{ARGUMENT-LIST}} and {{ENVIRONMENT-LIST}}. {{MODE}}
 88specifies how exactly the process should be executed and must be one
 89or more of the {{spawn/...}} flags listed below.
 90
 91The {{EXACT-FLAG}}, default {{#f}}, controls quote-wrapping of
 92argument strings. When {{#t}} quote-wrapping is not performed.
 93
 94Returns:
 95* the exit status when synchronous
 96* a process object when asynchronous
 97
 98'''NOTE''': On all Unix-like builds (all except native MingW-based
 99Windows platforms), this procedure is unimplemented and will raise an
100error.
101
102<constant>spawn/overlay</constant>
103<constant>spawn/wait</constant>
104<constant>spawn/nowait</constant>
105<constant>spawn/nowaito</constant>
106<constant>spawn/detach</constant>
107
108These variables contains special flags that specify the exact
109semantics of {{process-spawn}}:
110
111* {{spawn/overlay}} replaces the current process with the new one.
112* {{spawn/wait}} suspends execution of the current process until the spawned process returns.
113* {{spawn/nowait}} does the opposite ({{spawn/nowaito}} is identical, according to the Microsoft documentation) and runs the process asynchronously.
114* {{spawn/detach}} runs the new process in the background, without being attached to a console.
115
116
117==== process-wait
118
119<procedure>(process-wait [PROCESS [NOHANG]])</procedure>
120
121Suspends the current process until the child process identifier by {{PROCESS}},
122which should be a process object or an integer process id (pid),
123has terminated using the UNIX system call
124{{waitpid()}}. If {{PROCESS}} is not given, then this procedure
125waits for any child process. If {{NOHANG}} is given and not
126{{#f}} then the current process is not suspended.  This procedure
127returns three values:
128
129* {{PID}} or 0, if {{NOHANG}} is true and the child process has not terminated yet.
130* {{#t}} if the process exited normally or {{#f}} otherwise.
131* either the exit status, if the process terminated normally or the signal number that terminated/stopped the process.
132
133Note that suspending the current process implies that all threads
134are suspended as well.
135
136The exit status and the flag indicating whether the process returned normally
137are also stored in {{PROCESS}}, when given to be retrieved later, if desired.
138
139On Windows, {{process-wait}} always returns {{#t}} for a terminated
140process and only the exit status is available. (Windows does not
141provide signals as an interprocess communication method.)
142
143
144==== process-sleep
145
146<procedure>(process-sleep SECONDS)</procedure>
147
148Puts the process to sleep for {{SECONDS}}. Returns either 0 if
149the time has completely elapsed, or the number of remaining seconds,
150if a signal occurred.
151
152
153==== process
154
155<procedure>(process COMMANDLINE)</procedure><br>
156<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>
157
158Creates a subprocess and returns a process object, with the input-, output- and
159error ports stored in the object, which can be accessed using accessors described
160below.
161
162* The single parameter version passes the string {{COMMANDLINE}} to the host-system's shell that
163is invoked as a subprocess.
164* The multiple parameter version directly invokes the {{COMMAND}} as a subprocess. The {{ARGUMENT-LIST}}
165is directly passed, as is {{ENVIRONMENT-ALIST}}. These arguments have the same form as the ones of {{process-execute}}.
166
167{{ENCODING}} should be a symbol specifying the encoding to be
168used for I/O operations, the default is {{utf-8}}. The encodings for
169the returned in and output ports can be subsequently changed by
170using the {{port-encoding}} setter.
171
172Not using the shell may be preferrable for security reasons.
173
174Once both the input- and output ports are closed, an implicit
175{{waitpid(3)}} is done to wait for the subprocess to finish or to reap
176a subprocess that has terminated. If the subprocess has not finished,
177waiting for it will necessarily block all executing threads. The exit status
178and whether the process exitted normally will be stored in the returned
179process object to be retrieved later by the accessors described below,
180if so desired.
181
182==== process*
183
184<procedure>(process* COMMANDLINE)</procedure><br>
185<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST ENCODING])</procedure>
186
187Like {{process}} but returns 4 values: an input port from
188which data written by the sub-process can be read, an output port from
189which any data written to will be received as input in the sub-process,
190the process-id of the started sub-process, and an input port from
191which data written by the sub-process to {{stderr}} can be read.
192
193==== process?
194==== process-id
195==== process-exit-status
196==== process-returned-normally?
197==== process-input-port
198==== process-output-port
199==== process-error-port
200
201<procedure>(process? X)</procedure>
202
203Returns a boolean indicating whether {{X}} is a process object.
204
205<procedure>(process-id PROCESS)</procedure>
206<procedure>(process-exit-status PROCESS)</procedure>
207<procedure>(process-returned-normally? PROCESS)</procedure>
208<procedure>(process-input-port PROCESS)</procedure>
209<procedure>(process-output-port PROCESS)</procedure>
210<procedure>(process-error-port PROCESS)</procedure>
211
212Accessors for process-object attributes. The ports values are only
213defined for processes created with {{process}} or {{process*}} and represent
214the input port from
215which data written by the sub-process can be read, the output port from
216which any data written to will be received as input in the sub-process
217and the error port where to which the sub-process directs its error output.
218Blocking reads and writes
219to or from the ports returned by {{process}} only block the current
220thread, not other threads executing concurrently.
221
222Standard error for the subprocess is linked up to the current
223process's standard error (see {{process*}} if you want to reify
224its standard error into a separate port).
225
226=== Shell commands
227
228The commands below are all string-based.  This means you have to be
229very careful to properly quote any arguments to subprocesses, to avoid
230shell injection bugs which can lead to arbitrary code execution.
231
232You can quote arguments with the {{qs}} procedure, but it is strongly
233recommended you use {{fork}} with {{process-execute}} or the
234multi-argument versions of the {{process}}, {{process*}} or
235{{process-run}} procedures.
236
237==== qs
238
239<procedure>(qs STRING [PLATFORM])</procedure>
240
241Escapes {{STRING}} suitably for passing to a shell command on {{PLATFORM}}.
242{{PLATFORM}} defaults to the value of {{(build-platform)}} and indicates in
243which style the argument should be quoted. On Windows systems, the string
244is simply enclosed in double-quote ({{"}}) characters, on UNIXish systems,
245characters that would have a special meaning to the shell are escaped
246using backslash ({{\}}).
247
248
249==== system
250
251<procedure>(system STRING)</procedure>
252
253Execute shell command. The functionality offered by this procedure
254depends on the capabilities of the host shell. If the forking of a subprocess
255failed, an exception is raised. Otherwise the return status of the
256subprocess is returned unaltered.
257
258
259On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status.    It is 0 on success.  To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this:
260
261<enscript highlight='scheme'>
262;; Returns two values: #t if the process exited normally or #f otherwise;
263;; and either the exit status, or the signal number if terminated via signal.
264(define (process-status rc)
265  (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
266  (define (wait-signal x) (bitwise-and x 127))
267  (define (wait-exit-status x) (arithmetic-shift x -8))
268  (if (wait-signaled? rc)
269      (values #f (wait-signal rc))
270      (values #t (wait-exit-status rc))))
271
272#;> (process-status (system "exit 42"))
273#t
27442
275</enscript>
276
277==== system*
278
279<procedure>(system* STRING)</procedure>
280
281Similar to {{(system STRING)}}, but signals an error should the invoked
282program return a nonzero exit status.
283
284=== Pipes
285
286==== call-with-input-pipe
287==== call-with-output-pipe
288
289<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure><br>
290<procedure>(call-with-output-pipe CMDLINE PROC [MODE])</procedure>
291
292Call {{PROC}} with a single argument: a input- or output port
293for a pipe connected to the subprocess named in {{CMDLINE}}. If
294{{PROC}} returns normally, the pipe is closed and any result values
295are returned.
296
297==== close-input-pipe
298==== close-output-pipe
299
300<procedure>(close-input-pipe PORT)</procedure><br>
301<procedure>(close-output-pipe PORT)</procedure>
302
303Closes the pipe given in {{PORT}} and waits until the connected
304subprocess finishes. The exit-status code of the invoked process
305is returned.
306
307==== create-pipe
308
309<procedure>(create-pipe)</procedure>
310
311The fundamental pipe-creation operator. Calls the C function
312{{pipe()}} and returns 2 values: the file-descriptors of the input-
313and output-ends of the pipe.
314
315On Windows, there is an optional parameter {{MODE}}, which defaults
316to {{open/binary | open/noinherit}}. This can be {{open/binary}} or
317{{open/text}}, optionally or'ed with {{open/noinherit}}.
318
319
320==== open-input-pipe
321
322<procedure>(open-input-pipe CMDLINE [MODE])</procedure>
323
324Spawns a subprocess with the command-line string {{CMDLINE}} and
325returns a port, from which the output of the process can be read. If
326{{MODE}} is specified, it should be the keyword {{#:text}}
327(the default) or {{#:binary}}.
328
329==== open-output-pipe
330
331<procedure>(open-output-pipe CMDLINE [MODE])</procedure>
332
333Spawns a subprocess with the command-line string {{CMDLINE}} and
334returns a port. Anything written to that port is treated as the input
335for the process.  If {{MODE}} is specified, it should be the keyword
336{{#:text}} (the default) or {{#:binary}}.
337
338==== pipe/buf
339
340<constant>pipe/buf</constant>
341
342This variable contains the maximal number of bytes that can be written
343atomically into a pipe or FIFO.
344
345==== with-input-from-pipe
346==== with-output-to-pipe
347
348<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br>
349<procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure>
350
351Temporarily set the value of
352{{current-input-port/current-output-port}} to a port for a
353pipe connected to the subprocess named in {{CMDLINE}} and call
354the procedure {{THUNK}} with no arguments. After {{THUNK}}
355returns normally the pipe is closed and the standard input-/output port
356is restored to its previous value and any result values are returned.
357
358<enscript highlight=scheme>
359(with-output-to-pipe
360  "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -"
361  (lambda ()
362    (print #<<EOF
363 %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx>
364 /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8
365 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A
366 X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A
367 F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d
368 Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d
369 ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M
370 V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J
371 cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage
372 EOF
373 ) ) )
374</enscript>
375
376=== Windows specific notes
377
378Use of UTF8 encoded strings for pathnames is not supported. Windows
379uses a 16-bit UNICODE encoding with special system calls for
380wide-character support.  Only single-byte string encoding can be used.
381
382---
383Previous: [[Module (chicken pretty-print)]]
384
385Next: [[Module (chicken process signal)]]
Trap